import { IElement } from "./IElement.js";

export class IImage extends IElement {
    constructor() {
        super();
        this.SetTagName("IImage");
        this.SetStyleDisplay("inline-block");

        this.SetFit("fill");
        this.SetAttributeSetterGetter("src", (value) => { this.SetSrc(value); });
        this.SetAttributeSetterGetter("fit", (value) => { this.SetFit(value); })
        this.SetAttributeSetterGetter("width", (value) => { this.SetAttrWidth(value); });
        this.SetAttributeSetterGetter("height", (value) => { this.SetAttrHeight(value); });
    }

    SetFit(fit) { this.m_fit = fit; }
    SetAttrWidth(width) { this.m_attr_width = parseFloat(width); }
    SetAttrHeight(height) { this.m_attr_height = parseFloat(height); }

    SetSrc(src) {
        this.m_src = src;
        this.m_image = new Image();
        this.m_image.src = src;
        this.m_image.onload = () => {
            this.m_image_width = this.m_image.width;
            this.m_image_height = this.m_image.height;
            if (this.m_style_width < 0 || this.m_style_height < 0) {
                this.MarkLayoutChanged();
            }
        };
    }

    OnRenderContent(painter) {
        if (!this.m_image) return;
        const content_x = this.GetContentX();
        const content_y = this.GetContentY();
        const max_content_width = this.GetMaxContentWidth();
        const max_content_height = this.GetMaxContentHeight();
        if (!this.m_image_width || !this.m_image_height) return;
        if (this.m_fit == "cover") {
            const width_ratio = max_content_width / this.m_image_width;
            const height_ratio = max_content_height / this.m_image_height;
            const ratio = Math.max(width_ratio, height_ratio);
            painter.FillImage(this.m_image, content_x, content_y, this.m_image_width * ratio, this.m_image_height * ratio);
        }
        else if (this.m_fit == "contain") {
            const width_ratio = max_content_width / this.m_image_width;
            const height_ratio = max_content_height / this.m_image_height;
            const ratio = Math.min(width_ratio, height_ratio);
            painter.FillImage(this.m_image, content_x, content_y, this.m_image_width * ratio, this.m_image_height * ratio)
        }
        else if (this.m_fit == "fill") {
            painter.FillImage(this.m_image, content_x, content_y, max_content_width, max_content_height);
        }
        else if (this.m_fit == "scale-down") {
            if (this.m_image_width <= max_content_width && this.m_image_height <= max_content_height) {
                painter.FillImage(this.m_image, content_x, content_y, this.m_image_width, this.m_image_height);
            } else {
                const width_ratio = max_content_width / this.m_image_width;
                const height_ratio = max_content_height / this.m_image_height;
                const ratio = Math.min(width_ratio, height_ratio);
                painter.FillImage(this.m_image, content_x, content_y, this.m_image_width * ratio, this.m_image_height * ratio);
            }
        }
        else {
            painter.FillImage(this.m_image, content_x, content_y, this.m_image_width, this.m_image_height);
        }
    }

    GetLayoutWidth() {
        const local_width = this.GetLocalWidth();
        if (local_width > 0) return local_width;
        // 元素样式宽高被设置, 则返回元素样式宽高
        const style_width = this.GetStyleWidth();
        if (style_width >= 0) return style_width;
        // 获取测量宽
        return this.m_attr_width || this.m_image_width || 0;
    }

    GetLayoutHeight() {
        const local_height = this.GetLocalHeight();
        if (local_height > 0) return local_height;
        // 元素样式宽高被设置, 则返回元素样式宽高
        const style_height = this.GetStyleHeight();
        if (style_height >= 0) return style_height;
        // 获取行高
        return this.m_attr_height || this.m_image_height || 0;
    }

    UpdateLayout() {
        if (this.IsAutoWidth()) this.SetLocalWidth(this.GetLayoutWidth());
        if (this.IsAutoHeight()) this.SetLocalHeight(this.GetLayoutHeight());
        super.UpdateLayout();
    }
}